home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ZED3DSRC.ZIP
/
OBJECTS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-19
|
5KB
|
333 lines
#include <stdlib.h>
#include <objects.h>
pointcollection *alloc_pointcollection(int numpoints)
{
pointcollection *p;
p=malloc(sizeof(pointcollection)); /* try to allocate */
if(!p)
return 0; /* if fail to allocate, return error */
p->vertex=malloc(sizeof(point)*numpoints);
/* Allocate room for the vertices in the pointcollection */
if(!p->vertex)
{
free_pointcollection(p); /* if failure to allocate free it and */
return 0; /* return error */
}
p->numpoints=numpoints; /* put the number of points in the object
struct */
return p; /* return the newly created object struct */
}
void free_pointcollection(pointcollection *p)
{
if(p) /* if p is not the null object */
{
if(p->vertex) /* if p->vertex exists */
free(p->vertex); /* destroy it */
/* just for safety, overwrite all pointers with zeroes */
p->vertex=0;
free(p);
}
}
facecollection *alloc_facecollection(int numfaces)
{
facecollection *f;
long a;
f=malloc(sizeof(facecollection));
if(!f)
return 0;
f->face=malloc(sizeof(face)*numfaces);
if(!f->face)
{
free_facecollection(f);
return 0;
}
for(a=0;a<numfaces;a++)
f->face[a].index=0;
f->numfaces=numfaces;
return f;
}
void free_facecollection(facecollection *f)
{
long a;
if(f)
{
if(f->face)
{
for(a=0;a<f->numfaces;a++)
{
if(f->face[a].index)
{
free(f->face[a].index);
f->face[a].index=0;
}
}
free(f->face);
f->face=0;
}
free(f);
}
}
object *alloc_object(long numpoints, long numfaces)
{
object *o;
o=malloc(sizeof(object));
if(!o)
return 0;
o->pts_data=alloc_pointcollection(numpoints);
o->face_data=alloc_facecollection(numfaces);
o->usecount=1;
if((!o->pts_data)||(!o->face_data))
{
free_object(o);
return 0;
}
return o;
}
void free_object(object *o)
{
if(o)
{
o->usecount--;
if(o->usecount==0)
{
free_pointcollection(o->pts_data);
o->pts_data=0;
free_facecollection(o->face_data);
o->face_data=0;
}
}
}
object *clone_object(object *o)
{
o->usecount++;
return o;
}
REAL compute_2area(face *f, point *p, int axis1, int axis2)
{
long a,b,c,x,y,z;
REAL area;
b=f->index[f->numpoints-1];
area=floattoreal(0.0);
for(a=0;a<f->numpoints;a++)
{
/* for each edge, compute signed area of trapeze */
c=f->index[a];
/* edge goes from point #b to point #c */
area+=mul(
p[c].location[axis2]+p[b].location[axis2],
p[c].location[axis1]-p[b].location[axis1]);
b=c;
}
return area;
}
void normalize_object(object *o)
{
face *f;
long a,b,c;
#ifdef __vertexnormals__
point *p;
#endif
#ifdef __vertexnormals__
p=o->pts_data->vertex;
for(a=0;a<o->pts_data->numpoints;a++,p++)
{
vec_normalize(p->normal);
}
#endif
f=o->face_data->face;
for(a=0;a<o->face_data->numfaces;a++,f++)
{
vec_normalize(f->normal);
}
fix_D(o);
}
void init_normals(object *o)
{
long a,b,c,x,y,z;
face *f;
point *p;
p=o->pts_data->vertex;
f=o->face_data->face;
for(a=0;a<o->pts_data->numpoints;a++)
{
#ifdef __vertexnormals__
initvector(p[a].normal,0,0,0);
#endif
p[a].clipping=0;
}
for(a=0;a<o->face_data->numfaces;a++,f++)
{
f->normal[0]=compute_2area(f,p,1,2);
f->normal[1]=compute_2area(f,p,2,0);
f->normal[2]=compute_2area(f,p,0,1);
for(b=0;b<f->numpoints;b++)
{
#ifdef __vertexnormals__
vec_add(p[f->index[b]].normal,p[f->index[b]].normal,f->normal);
#endif
p[f->index[b]].clipping++;
}
}
fix_D(o);
}
void fix_D(object *o)
{
face *f;
point *p;
long a;
p=o->pts_data->vertex;
f=o->face_data->face;
for(a=0;a<o->face_data->numfaces;a++,f++)
f->D=vec_dot(f->normal,p[*f->index].location);
}
int init_facepts(face *f, long numpoints)
{
f->index=malloc(sizeof(long)*numpoints);
if(f->index==0)
return -1;
f->numpoints=numpoints;
return 0;
}
int make_tetrahedron(object *o)
{
face *f;
point *p;
long a,b,c,doit;
REAL A,B,C,D;
f=o->face_data->face;
for(a=0;a<4;a++,f++)
{
if(init_facepts(f,3))
return 0;
}
f=o->face_data->face;
for(a=0;a<4;a++,f++)
{
for(b=0,c=0;b<3;b++,c++)
{
if(c==a)
c++;
f->index[b]=c;
}
}
p=o->pts_data->vertex;
init_normals(o);
doit=0;
p=o->pts_data->vertex;
f=o->face_data->face;
for(a=0;a<4;a++,f++)
{
for(b=0,A=floattoreal(0.0);b<4;b++)
{
B=vec_dot(f->normal,p[b].location);
B-=f->D;
C=mul(B,B);
if(C>A)
{
A=C;
D=B;
}
}
if(A<floattoreal(0.001))
{
doit=-1;
break;
}
if(D>0)
vec_mul_scl(f->normal,f->normal,floattoreal(-1));
}
fix_D(o);
return doit;
}